package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"
	"vidproc/internal/config"
	"vidproc/internal/processor"
)

type Progress struct {
	Total     int
	Processed int
	mu        sync.Mutex
}

func (p *Progress) Increment() {
	p.mu.Lock()
	p.Processed++
	p.mu.Unlock()
}

func (p *Progress) GetProgress() (int, int) {
	p.mu.Lock()
	defer p.mu.Unlock()
	return p.Processed, p.Total
}

func main() {
	startTime := time.Now()

	// 加载配置
	cfg, err := config.LoadConfig("config/config.yaml")
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 创建视频处理器
	videoProcessor := processor.NewVideoProcessor(cfg)

	// 创建工作池
	pool, err := processor.NewWorkerPool(cfg)
	if err != nil {
		log.Fatalf("Failed to create worker pool: %v", err)
	}

	// 启动工作池
	if err := pool.Start(); err != nil {
		log.Fatalf("Failed to start worker pool: %v", err)
	}
	defer pool.Stop()

	// 用于等待所有任务完成
	var wg sync.WaitGroup
	var processError error
	var errorMu sync.Mutex

	// 统计总文件数
	var totalFiles int
	filepath.Walk(cfg.InputDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			ext := filepath.Ext(path)
			if ext == ".mp4" || ext == ".mkv" || ext == ".avi" {
				totalFiles++
			}
		}
		return nil
	})

	progress := &Progress{Total: totalFiles}

	// 启动进度显示协程
	go func() {
		ticker := time.NewTicker(1 * time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				processed, total := progress.GetProgress()
				elapsed := time.Since(startTime)
				fmt.Printf("\r进度: %d/%d (%.1f%%) | 耗时: %v | 当前工作协程数: %d",
					processed, total, float64(processed)/float64(total)*100,
					elapsed.Round(time.Second), pool.GetWorkerCount())
			}
		}
	}()

	// 处理输入目录中的所有视频文件
	err = filepath.Walk(cfg.InputDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			return nil
		}

		// 只处理视频文件
		ext := filepath.Ext(path)
		if ext != ".mp4" && ext != ".mkv" && ext != ".avi" {
			return nil
		}

		// 获取文件名（不含扩展名）
		filename := filepath.Base(path)
		name := filename[:len(filename)-len(ext)]

		// 创建处理任务
		wg.Add(1)
		task := func() error {
			defer wg.Done()
			defer progress.Increment()

			// 生成低质量视频
			lowOutput := filepath.Join(cfg.OutputDirs.Low, name+".mp4")
			if err := videoProcessor.GenerateLowQuality(path, lowOutput); err != nil {
				return fmt.Errorf("failed to generate low quality video for %s: %v", path, err)
			}

			// 生成 WebM 视频
			webmOutput := filepath.Join(cfg.OutputDirs.WebM, name+".webm")
			if err := videoProcessor.GenerateWebM(path, webmOutput); err != nil {
				return fmt.Errorf("failed to generate WebM video for %s: %v", path, err)
			}

			// 生成缩略图
			posterOutput := filepath.Join(cfg.OutputDirs.Posters, name+".webp")
			if err := videoProcessor.GeneratePoster(path, posterOutput); err != nil {
				return fmt.Errorf("failed to generate poster for %s: %v", path, err)
			}

			return nil
		}

		// 提交任务到工作池
		if err := pool.Submit(task); err != nil {
			errorMu.Lock()
			processError = err
			errorMu.Unlock()
			return err
		}

		return nil
	})

	// 等待所有任务完成
	wg.Wait()

	if err != nil {
		log.Fatalf("Error walking through directory: %v", err)
	}

	if processError != nil {
		log.Fatalf("Error processing videos: %v", processError)
	}

	totalTime := time.Since(startTime)
	fmt.Printf("\n处理完成！总耗时: %.2fs\n", totalTime.Seconds())
	fmt.Printf("并发模式: %s, 最终工作协程数: %d\n", cfg.ConcurrencySettings.Mode, pool.GetWorkerCount())
}
